package il.ac.braude.sona.gui.list_table;


import java.lang.reflect.Field;
import java.util.ArrayList;

import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

/**
 * The ListTableModel contains all methods for initialize the table model of change requests
 *  
 * @author Ofek Ron
 * @author Avihay Avitan
 * @author Nitzan Inbar
 * @author Sasha Rozenblum
 */
public class ListTableModel<T> implements TableModel {
	/**
	 * listeners - Array List of Table Model Listeners
	 */
	private ArrayList<TableModelListener> listeners = new ArrayList<TableModelListener>();
	/**
	 * mElements - Array List of Table Model Elements
	 */
	private ArrayList<T> mElements;
	/**
	 * representingItem - The items to display
	 */
	private T representingItem;
	/**
	 * fields - The field names of items
	 */
	private ArrayList<Field> fields = new ArrayList<Field>();
	/**
	 * Constructs the ListTableModel.
	 * initialize the items to be displayed in the table
	 * @param req - ArrayList of change requests items to display
	 */
	public ListTableModel(ArrayList<T> req) {
		mElements=req;
		if (mElements.size()>0) {
			representingItem=mElements.get(0);
			for (Field f : representingItem.getClass().getDeclaredFields()) {
				FieldInfo anno = f.getAnnotation(FieldInfo.class);
				if (anno!=null && anno.isVisibleOnTable()) fields.add(f);
			}
				
		}
		
	}
	
	/**
	 * Gets the change request at row i
	 * @param i - The row index of the requested ChangeRequest
	 * @return mElements.get(i) - the ChangeRequest 
	 */
	public T getChangeRequest(int i) {
		return mElements.get(i);
	}
	/**
	 * Add listener to TableModel
	 * @param l - The TableModelListener to add
	 */
	@Override
	public void addTableModelListener(TableModelListener l) {
		if (!listeners.contains(l))
			listeners.add(l);
	}

	@Override
	public Class<?> getColumnClass(int arg0) {
		return String.class;
	}
	/**
	 * Gets the element at row i
	 * @param i - The row index of the requested element
	 * @return mElements.get(i) - the element 
	 */
	public T get(int i) {
		return mElements.get(i);
	}


	@Override
	public int getRowCount() {
		return mElements.size();
	}


	@Override
	public boolean isCellEditable(int arg0, int arg1) {
		return false;
	}

	@Override
	public void removeTableModelListener(TableModelListener l) {
		listeners.remove(l);
	}

	@Override
	public void setValueAt(Object arg0, int arg1, int arg2) {
	}
	
	@Override
	public int getColumnCount() {

		
		return fields.size();
	}
	@Override
	public String getColumnName(int columnIndex) {
		return fields.get(columnIndex).getAnnotation(FieldInfo.class).name();
	}
	@Override
	public Object getValueAt(int rowIndex, int columnIndex) {
		try {
			Field f = fields.get(columnIndex);
			boolean b = f.isAccessible();
			f.setAccessible(true);
			Object value = f.get(get(rowIndex));
			f.setAccessible(b);
			return value;
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

}
